﻿using Base.Api.Models;
using Base.Api.Repository;
using Base.Data.Entity;
using Base.Data.Entity.Base;
using Castle.Core.Internal;
using Common.AspNetCore;
using Common.Enums.Base;
using Common.Enums.FCP;
using Common.Infrastructure;
using Common.Infrastructure.Service;
using Common.Infrastructure.Structs;
using Common.Infrastructure.Utils;
using Common.Models.Base;
using Common.RunModels.Base;
using Microsoft.Extensions.Configuration;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Threading.Tasks;

namespace Base.Api.Service
{
    public class BaseDataService : CommonService
    {
        private readonly BaseRepository baseRepository;
        private readonly IConfiguration configuration;
        private readonly IUserTokenService tokenService;

        public BaseDataService(IServiceProvider provider, IConfiguration configuration, BaseRepository baseRep, IUserTokenService tokenService) : base(provider)
        {
            this.configuration = configuration;
            this.baseRepository = baseRep;
            this.tokenService = tokenService;
        }

        public async Task<UserModel> GetUserAsync(ApiParam apiParam)
        {
            if (string.IsNullOrEmpty(apiParam.Keyword))
            {
                throw new CommonException("keyword is request");
            }

            var m = await this.baseRepository.CommonRepository.GetEntityAsync<t_user>(apiParam.Keyword);
            return GetUserModel(m);
        }

        public async Task<List<UserModel>> GetUsersAsync(ApiParam apiParam)
        {
            if (string.IsNullOrEmpty(apiParam.Keyword))
            {
                throw new CommonException("keyword is request");
            }

            var ids = apiParam.Keyword.Split(',', StringSplitOptions.RemoveEmptyEntries).ToList();
            var m = await this.baseRepository.CommonRepository.GetEntitiesAsync<t_user>(ids);
            if (m != null && m.Any())
            {
                return m.Select(t => GetUserModel(t)).ToList();
            }

            return null;
        }

        public async Task<UserModel> GetUserByCodeAsync(ApiParam apiParam)
        {
            if (string.IsNullOrEmpty(apiParam.Keyword))
            {
                throw new CommonException("keyword is request");
            }

            var m = await this.baseRepository.CommonRepository.GetEntityAsync<t_user>(new ApiParam(apiParam.OrgId) { OrgType = FilterOrgTypeEnum.OnlyOrg }, t => t.code == apiParam.Keyword);
            return GetUserModel(m);
        }

        public async Task<List<UserModel>> GetUserByCodesOrNamesAsync(ApiParam apiParam)
        {
            var userNames = apiParam.Keyword?.Split(',', StringSplitOptions.RemoveEmptyEntries).ToList() ?? new List<string>();
            var userCodes = apiParam.Params.FirstOrDefault(t => t.Key == "Codes" || t.Key == "code" || t.Key == "codes")?.Value?.Split(',', StringSplitOptions.RemoveEmptyEntries).ToList() ?? new List<string>();
            if (!userNames.Any() && !userCodes.Any())
            {
                return new List<UserModel>();
            }

            Expression<Func<t_user, bool>> expression = t => t.org_id == apiParam.OrgId && (userCodes.Contains(t.code) || userCodes.Contains(t.user_lcp_code) || userNames.Contains(t.name));
            var users = await this.baseRepository.CommonRepository.GetEntitiesAsync<t_user>(expression);
            return users?.Select(t => this.GetUserModel(t)).ToList();
        }

        public async Task<UserFullModel> GetUserFullAsync(ApiParam apiParam)
        {
            if (string.IsNullOrEmpty(apiParam.Keyword))
            {
                throw new CommonException("keyword is request");
            }

            var m = await this.baseRepository.CommonRepository.GetEntityAsync<t_user>(apiParam.Keyword);
            var p = m != null && !string.IsNullOrEmpty(m.user_post_id) ? await this.baseRepository.CommonRepository.GetEntityAsync<t_user_post>(m.user_post_id) : null;
            return GetUserFullModel(m, p);
        }

        public async Task<UserFullModel> GetUserFullByCodeAsync(ApiParam apiParam)
        {
            if (string.IsNullOrEmpty(apiParam.Keyword))
            {
                throw new CommonException("keyword is request");
            }

            var m = await this.baseRepository.CommonRepository.GetEntityAsync<t_user>(new ApiParam(apiParam.OrgId) { OrgType = FilterOrgTypeEnum.OnlyOrg }, t => t.code == apiParam.Keyword);
            var p = m != null && !string.IsNullOrEmpty(m.user_post_id) ? await this.baseRepository.CommonRepository.GetEntityAsync<t_user_post>(m.user_post_id) : null;
            return GetUserFullModel(m, p);
        }

        public async Task<List<UserFullModel>> GetUserFullByIdsAsync(ApiParam apiParam)
        {
            if (string.IsNullOrEmpty(apiParam.Keyword))
            {
                throw new CommonException("keyword is request");
            }

            var ids = apiParam.Keyword.Split(',').ToList();
            var users = await this.baseRepository.CommonRepository.GetEntitiesAsync<t_user>(ids);
            var postIds = users.Where(t => !string.IsNullOrEmpty(t.user_post_id)).Select(t => t.user_post_id).ToList();
            var p = postIds.Any() ? await this.baseRepository.CommonRepository.GetEntitiesAsync<t_user_post>(postIds) : null;
            List<UserFullModel> ret = new List<UserFullModel>();
            users.ForEach(t =>
            {
                var post = p?.FirstOrDefault(t1 => t1.id == t.user_post_id);
                ret.Add(GetUserFullModel(t, post));
            });
            return ret;
        }

        public async Task<List<UserModel>> GetUserFullByOrgAsync(ApiParam apiParam)
        {
            if (string.IsNullOrEmpty(apiParam.OrgId))
            {
                throw new CommonException("OrgId is request");
            }

            var users = await this.baseRepository.CommonRepository.GetEntitiesAsync<t_user>(t => t.org_id == apiParam.OrgId);

            List<UserModel> ret = new List<UserModel>();
            users.ForEach(t =>
            {
                ret.Add(GetUserModel(t));
            });
            return ret;
        }

        public async Task<List<SectionBandingLine>> GetSectionBandingLinesAsync(ApiParam apiParam)
        {
            if (string.IsNullOrEmpty(apiParam.Keyword))
            {
                throw new CommonException("Keyword is request");
            }

            var result = new List<SectionBandingLine>();
            var codes = apiParam.Keyword.Split(',').ToList();
            var deps = await this.baseRepository.CommonRepository.GetEntitiesAsync<t_department>(p => codes.Contains(p.code));
            var parentIds = deps.GroupBy(p => p.parent_id).Select(t => t.Key).ToList();
            var parentDeps = await this.baseRepository.CommonRepository.GetEntitiesAsync<t_department>(parentIds);
            if (parentDeps == null || !parentDeps.Any())
            {
                return null;
            }

            parentDeps.ForEach((o) =>
            {
                var item = new SectionBandingLine();
                item.SectionCode = o.code;
                item.SectionId = o.id;
                item.SectionName = o.name;
                item.LineCodes = deps.Where(p => p.parent_id == o.id).Select(t => t.code).ToList();
                result.Add(item);
            });

            return result;
        }

        /// <summary>
        /// 获取用户负责的线体
        /// </summary>
        /// <param name="apiParam"></param>
        /// <returns></returns>
        /// <exception cref="CommonException"></exception>
        public async Task<List<LineModel>> GetLineModelByUserIdAsync(ApiParam apiParam)
        {
            if (string.IsNullOrEmpty(apiParam.Keyword))
            {
                throw new CommonException("Keyword is request");
            }

            var result = new List<LineModel>();
            var userIds = apiParam.Keyword.Split(',').ToList();
            //// 获取用户负责的部门
            var deps = await this.baseRepository.CommonRepository.GetEntitiesAsync<t_department>(p => userIds.Contains(p.user_id) && p.is_line);
            var parentIds = deps.GroupBy(p => p.parent_id).Select(t => t.Key).ToList();
            var parentDeps = await this.baseRepository.CommonRepository.GetEntitiesAsync<t_department>(parentIds);
            if (parentDeps == null || !parentDeps.Any())
            {
                return result;
            }

            ///var userIds = deps.Where(p => p.user_id != null).Select(p => p.user_id).Concat(parentDeps.Where(p => p.user_id != null).Select(t => t.user_id)).Distinct().ToList();
            var users = await this.GetDepartmentUserModels(userIds);
            deps.ForEach(o =>
            {
                var user = users.FirstOrDefault(p => p.UserId == o.user_id);
                var session = parentDeps.FirstOrDefault(p => p.id == o.parent_id);
                var sectionUser = users.FirstOrDefault(p => p.UserId == session?.user_id);
                var item = new LineModel();
                //// 课长
                item.SectionName = session?.name;
                item.SectionId = session?.id;
                item.SectionChief = sectionUser?.UserName;
                item.LineId = o.id;
                item.LineName = o.name;
                item.LineCode = o.code;
                item.LineChief = user?.UserName;
                result.Add(item);
            });

            return result;
        }

        public async Task<List<DepartmentModel>> GetDepartmentModelsAsync(ApiParam apiParam)
        {
            if (string.IsNullOrEmpty(apiParam.Keyword))
            {
                throw new CommonException("Keyword is request");
            }

            var result = new List<DepartmentModel>();
            var dep = await this.baseRepository.CommonRepository.GetEntityAsync<t_department>(apiParam.Keyword);
            var ids = new List<string>() { dep.id };
            GetdepIds(new List<string>() { dep.id }, ids);
            var deps = await this.baseRepository.CommonRepository.GetEntitiesAsync<t_department>(ids);
            if (deps == null || !deps.Any())
            {
                return null;
            }

            var users = await this.GetDepartmentUserModels(deps.Where(p => p.user_id != null).Select(p => p.user_id).ToList());
            deps.ForEach((o) =>
            {
                var item = new DepartmentModel();
                item.Code = o.code;
                item.AliasUserId = o.id;
                item.IsLine = o.is_line;
                item.Name = o.name;
                item.ParentId = o.parent_id;
                item.Remark = o.remark;
                item.UserId = o.user_id;
                item.Id = o.id;
                item.OrgId = o.org_id;
                item.DepartmentUserModels = users.Where(p => p.DepId == o.id).ToList();
                item.IsStatis = o.is_statis;
                result.Add(item);
            });

            return result;
        }

        /// <summary>
        /// 根据线体编号获取线体
        /// </summary>
        /// <param name="apiParam"></param>
        /// <returns></returns>
        /// <exception cref="CommonException"></exception>
        public async Task<List<LineModel>> GetLineModelsAsync(ApiParam apiParam)
        {
            if (string.IsNullOrEmpty(apiParam.Keyword))
            {
                throw new CommonException("Keyword is request");
            }

            var result = new List<LineModel>();
            var codes = apiParam.Keyword.Split(',').ToList();
            var lines = await this.baseRepository.CommonRepository.GetEntitiesAsync<t_department>(p => codes.Contains(p.code));

            if (!lines.Any())
            {
                throw new CommonException("lines is null");
            }

            var deps = await this.baseRepository.CommonRepository.GetEntitiesAsync<t_department>(p => p.org_id == lines.FirstOrDefault().org_id && p.level == (int)DepLevelEnum.部门);
            var sectionIds = lines.GroupBy(p => p.parent_id).Select(t => t.Key).ToList();
            var parentDeps = await this.baseRepository.CommonRepository.GetEntitiesAsync<t_department>(sectionIds);
            if (parentDeps == null || !parentDeps.Any())
            {
                return null;
            }

            var userIds = deps.Where(p => p.user_id != null).Select(p => p.user_id).Concat(lines.Where(p => p.user_id != null).Select(p => p.user_id).Concat(parentDeps.Where(p => p.user_id != null).Select(t => t.user_id))).Distinct().ToList();
            userIds.AddRange(deps.Where(p => !string.IsNullOrEmpty(p.alias_user_id)).Select(p => p.alias_user_id).Concat(lines.Where(p => p.alias_user_id != null).Select(p => p.alias_user_id).Concat(parentDeps.Where(p => p.alias_user_id != null).Select(t => t.alias_user_id))).Distinct().ToList());
            userIds = userIds.Distinct().ToList();

            var users = await this.GetDepartmentUserModels(userIds);
            lines.ForEach(o =>
            {
                var user = users.FirstOrDefault(p => p.UserId == o.user_id);
                var section = parentDeps.FirstOrDefault(p => p.id == o.parent_id);
                var sectionUser = users.FirstOrDefault(p => p.UserId == section?.user_id);
                var dep = deps.FirstOrDefault(p => p.id == section?.parent_id);
                var depUser = users.FirstOrDefault(p => p.UserId == dep?.user_id);
                var item = new LineModel();
                item.SectionName = section?.name;
                item.SectionId = section?.id;
                item.SectionChief = sectionUser?.UserName;
                item.LineId = o.id;
                item.LineName = o.name;
                item.LineCode = o.code;
                item.LineChief = user?.UserName;
                item.LineChiefId = user?.Id;
                item.SectionChiefId = sectionUser?.Id;
                item.DepChiefId = depUser?.Id;
                item.DepName = dep?.name;
                item.DepId = dep?.id;
                item.DepChief = depUser?.UserName;
                result.Add(item);
            });

            return result;
        }

        public async Task<ApiPagedResult<DepartModel>> GetTopDepartmentModelsAsync(ModelOrderPageRequest apiParam)
        {
            var result = new List<DepartModel>();
            var deps = await this.baseRepository.CommonRepository.GetEntitiesAsync<t_department>(null, t => t.is_line && t.org_id == apiParam.OrderPageParam.OrgId, null);
            if (deps == null || !deps.Any())
            {
                return null;
            }

            var ids = new List<string>();
            GetParentIds(deps.Select(t => t.parent_id).ToList(), ids);
            var parentDepts = await this.baseRepository.CommonRepository.GetEntitiesAsync<t_department>(ids);

            if (parentDepts == null || !parentDepts.Any())
            {
                return null;
            }

            parentDepts.ForEach((o) =>
            {
                var item = new DepartModel();
                item.DepartCode = o.code;
                item.DepartName = o.name;
                item.ParentId = o.parent_id;
                item.DepartId = o.id;
                item.id = o.id;
                item.ApiKey = o.api_key;
                result.Add(item);
            });

            ApiPagedResult<DepartModel> deptPage = new ApiPagedResult<DepartModel>();
            deptPage.Data = result;
            deptPage.TotalCount = result.Count;
            return deptPage;
        }

        public async Task<List<DepartModel>> GetLineDepartmentModelsAsync(ApiParam apiParam)
        {
            var result = new List<DepartModel>();
            var deps = await this.baseRepository.CommonRepository.GetEntitiesAsync<t_department>(null, t => t.org_id == apiParam.OrgId, null);
            if (deps == null || !deps.Any())
            {
                return null;
            }

            deps.ForEach((o) =>
            {
                var item = new DepartModel();
                item.DepartCode = o.code;
                item.DepartName = o.name;
                item.ParentId = o.parent_id;
                item.DepartId = o.id;
                item.id = o.id;
                item.UserId = o.user_id;
                item.IsLine = o.is_line;
                item.Level = o.level;
                item.IsStatis = o.is_statis;
                item.ApiKey = o.api_key;
                result.Add(item);
            });

            return result;
        }

        public async Task<ApiPagedResult<t_user>> GetLineChiefsUserAsync(ModelOrderPageRequest apiParam)
        {
            var result = new ApiPagedResult<t_user>();
            result.Data = new List<t_user>();
            var deps = await this.baseRepository.CommonRepository.GetEntitiesAsync<t_department>(t => t.is_line && t.org_id == apiParam.OrderPageParam.OrgId, null);
            if (deps == null || !deps.Any())
            {
                return null;
            }

            var userIds = deps.Where(t => t.user_id != null).Select(p => p.user_id).ToList();
            var users = await this.baseRepository.CommonRepository.GetOrderPageEntitiesAsync<t_user>(apiParam.OrderPageParam, p => userIds.Contains(p.id));
            if (users == null || users.Data == null || !users.Data.Any())
            {
                return null;
            }

            users.Data.ForEach(o =>
            {
                var item = new UserModel();
                item.Id = o.id;
                item.Code = o.code;
                item.Name = o.name;
                result.Data.Add(o);
            });

            result.TotalCount = users.TotalCount;
            return result;
        }

        public async Task<List<DepartModel>> GetDepartmentLevelModelsAsync(ApiParam apiParam)
        {
            if (string.IsNullOrEmpty(apiParam.Keyword))
            {
                throw new CommonException("Keyword is request");
            }

            var result = new List<DepartModel>();
            var dep = await this.baseRepository.CommonRepository.GetEntityAsync<t_department>(null, t => t.code == apiParam.Keyword);

            if (dep != null)
            {
                var ids = new List<string>() { dep.id };
                GetParentIds(new List<string>() { dep.id }, ids);
                var deps = await this.baseRepository.CommonRepository.GetEntitiesAsync<t_department>(ids);
                if (deps == null || !deps.Any())
                {
                    return null;
                }

                deps.ForEach((o) =>
                {
                    var item = new DepartModel();
                    item.DepartCode = o.code;
                    item.DepartName = o.name;
                    item.ParentId = o.parent_id;
                    item.DepartId = o.id;
                    item.ApiKey = o.api_key;
                    result.Add(item);
                });
            }

            return result;
        }

        public async Task<List<OrgCache>> GetOrgsAsync()
        {
            var orgs = await this.baseRepository.CommonRepository.GetEntitiesAsync<t_organization>(t => t.enable_status == 0);
            List<OrgCache> ret = new List<OrgCache>();
            orgs.ForEach(t =>
            {
                OrgCache o = new OrgCache
                {
                    Code = t.code,
                    Name = t.name,
                    Id = t.id,
                    ParentId = t.parent_id,
                    QMSBUCode = t.qms_bu_code,
                    AliasCode = t.alias_code,
                };
                ret.Add(o);
            });
            return ret;
        }

        public async Task<OrgCache> GetOrgsByIdAsync(string id)
        {
            var org = await this.baseRepository.CommonRepository.GetEntityAsync<t_organization>(id);
            OrgCache ret = new OrgCache()
            {
                Code = org.code,
                Name = org.name,
                Id = org.id,
                ParentId = org.parent_id,
                AliasCode = org.alias_code,
                QMSBUCode = org.qms_bu_code,
            };

            return ret;
        }

        public async Task<MemberModel> GetMemberByIdAsync(ApiParam apiParam)
        {
            if (string.IsNullOrEmpty(apiParam.Keyword))
            {
                throw new CommonException("keyword is request");
            }

            var m = await this.baseRepository.CommonRepository.GetEntityAsync<t_member>(apiParam.Keyword);
            return GetMemberModel(m);
        }

        public async Task<MemberModel> GetMemberByCodeAsync(ApiParam apiParam)
        {
            if (string.IsNullOrEmpty(apiParam.Keyword))
            {
                throw new CommonException("keyword is request");
            }

            var m = await this.baseRepository.CommonRepository.GetEntityAsync<t_member>(new ApiParam(apiParam.OrgId) { OrgType = FilterOrgTypeEnum.OnlyOrg }, t => t.code == apiParam.Keyword);
            return GetMemberModel(m);
        }

        public async Task<MemberModel> GetMemberByUserIdAsync(ApiParam apiParam)
        {
            if (string.IsNullOrEmpty(apiParam.Keyword))
            {
                throw new CommonException("keyword is request");
            }

            var m = await this.baseRepository.CommonRepository.GetEntityAsync<t_member>(new ApiParam(apiParam.OrgId) { OrgType = FilterOrgTypeEnum.OnlyOrg }, t => t.user_id == apiParam.Keyword);
            return GetMemberModel(m);
        }

        public async Task<MemberModel> GetMemberByUserCodeAsync(ApiParam apiParam)
        {
            if (string.IsNullOrEmpty(apiParam.Keyword))
            {
                throw new CommonException("keyword is request");
            }

            var m = await this.baseRepository.CommonRepository.GetEntityAsync<t_user>(new ApiParam(apiParam.OrgId) { OrgType = FilterOrgTypeEnum.OnlyOrg }, t => t.code == apiParam.Keyword);
            if (m == null)
            {
                return null;
            }

            var mm = await this.baseRepository.CommonRepository.GetEntityAsync<t_member>(new ApiParam(apiParam.OrgId) { OrgType = FilterOrgTypeEnum.OnlyOrg }, t => t.user_id == m.id);
            return GetMemberModel(mm);
        }

        public async Task<DepartModel> GetDepartByIdAsync(ApiParam apiParam)
        {
            if (string.IsNullOrEmpty(apiParam.Keyword))
            {
                throw new CommonException("keyword is request");
            }

            var m = await this.baseRepository.CommonRepository.GetEntityAsync<t_department>(apiParam.Keyword);
            return GetDepartModel(m);
        }

        public async Task<DepartModel> GetDepartParentByIdAsync(ApiParam apiParam)
        {
            if (string.IsNullOrEmpty(apiParam.Keyword))
            {
                throw new CommonException("keyword is request");
            }

            var m = await this.baseRepository.CommonRepository.GetEntityAsync<t_department>(apiParam.Keyword);

            var result = GetDepartModel(m);
            if (result == null)
            {
                return null;
            }

            var parent = await this.baseRepository.CommonRepository.GetEntityAsync<t_department>(m?.parent_id);
            result.ParentId = parent?.id;
            result.ParentCode = parent?.code;
            result.ParentName = parent?.name;
            return result;
        }

        public async Task<DepartModel> GetDepartByCodeAsync(ApiParam apiParam)
        {
            if (string.IsNullOrEmpty(apiParam.Keyword))
            {
                throw new CommonException("keyword is request");
            }

            var m = await this.baseRepository.CommonRepository.GetEntityAsync<t_department>(new ApiParam(apiParam.OrgId) { OrgType = FilterOrgTypeEnum.OnlyOrg }, t => t.code == apiParam.Keyword);
            return GetDepartModel(m);
        }

        public async Task<int> GetUserNumByDepartCodeAsync(ApiParam apiParam)
        {
            if (string.IsNullOrEmpty(apiParam.Keyword))
            {
                throw new CommonException("keyword is request");
            }

            var m = await this.baseRepository.CommonRepository.GetEntityAsync<t_department>(null, t => t.code == apiParam.Keyword);
            if (m != null)
            {
                return await this.baseRepository.CommonRepository.GetCountAsync<t_user>(null, t => t.depart_id == m.id && t.enable_status == 0);
            }

            return 0;
        }

        public async Task<string> GetOrgaliasCodeByOrgAsync(ApiParam apiParam)
        {
            if (string.IsNullOrEmpty(apiParam.Keyword))
            {
                throw new CommonException("keyword is request");
            }

            var m = await this.baseRepository.CommonRepository.GetEntityAsync<t_organization>(apiParam.Keyword);
            if (m != null)
            {
                return m.alias_code;
            }

            return string.Empty;
        }

        public async Task<DepartLineResultModel> GetDepartLineByDepartCodeAsync(DepartLineParamModel model)
        {
            DepartLineResultModel resultModel = new DepartLineResultModel();
            if (model.DepartCodes == null || !model.DepartCodes.Any())
            {
                return resultModel;
            }

            model.DepartCodes = model.DepartCodes.Distinct().ToList();
            var departments = await this.baseRepository.CommonRepository.GetEntitiesAsync<t_department>(t => model.DepartCodes.Contains(t.code));
            var parentIds = departments.Where(t => !string.IsNullOrEmpty(t.parent_id)).Select(t => t.parent_id).ToList();
            var parentDepartments = parentIds.Any() ? await this.baseRepository.CommonRepository.GetEntitiesAsync<t_department>(parentIds) : new List<t_department>();
            var topparentIds = parentDepartments.Where(t => !string.IsNullOrEmpty(t.parent_id)).Select(t => t.parent_id).ToList();
            var topparentDepartments = topparentIds.Any() ? await this.baseRepository.CommonRepository.GetEntitiesAsync<t_department>(topparentIds) : new List<t_department>();

            var alldeparts = new List<t_department>();
            alldeparts.AddRange(departments);
            alldeparts.AddRange(parentDepartments);
            alldeparts.AddRange(topparentDepartments);

            var userIds = alldeparts.Where(t => !string.IsNullOrEmpty(t.user_id)).Select(t => t.user_id).ToList();
            var aliasUserIds = alldeparts.Where(t => !string.IsNullOrEmpty(t.alias_user_id)).Select(t => t.alias_user_id).ToList();
            userIds.AddRange(aliasUserIds);
            var users = userIds.Any() ? await this.baseRepository.CommonRepository.GetEntitiesAsync<t_user>(userIds) : new List<t_user>();

            foreach (var depart in departments)
            {
                var user = users.FirstOrDefault(t => t.id == depart.user_id);
                var aliasuser = users.FirstOrDefault(t => t.id == depart.alias_user_id);
                var shopDepart = alldeparts.FirstOrDefault(t => t.id == depart.parent_id);
                var sectionDepart = shopDepart != null ? alldeparts.FirstOrDefault(t => t.id == shopDepart.parent_id) : null;

                var shopuser = users.FirstOrDefault(t => t.id == shopDepart?.user_id);
                var sectionuser = users.FirstOrDefault(t => t.id == sectionDepart?.user_id);

                DepartLineDetailResultModel detailResultModel = new DepartLineDetailResultModel()
                {
                    DepartCode = depart.code,
                    DepartName = depart.name,
                    UserCode = user?.code,
                    UserName = user?.name,
                    UserId = user?.id,
                    AliasUserCode = aliasuser?.code,
                    AliasUserId = aliasuser?.id,
                    AliasUserName = aliasuser?.name,
                    SectionDepartCode = sectionDepart?.code,
                    SectionDepartId = sectionDepart?.id,
                    SectionDepartName = sectionDepart?.name,
                    SectionUserCode = sectionuser?.code,
                    SectionUserId = sectionuser?.id,
                    SectionUserName = sectionuser?.name,
                    SectionUserPhone = sectionuser?.phone,
                    ShopDepartId = shopDepart?.id,
                    ShopDepartCode = shopDepart?.code,
                    ShopDepartName = shopDepart?.name,
                    ShopUserCode = shopuser?.code,
                    ShopUserId = shopuser?.id,
                    ShopUserName = shopuser?.name,
                    ShopUserPhone = shopuser?.phone,
                };

                resultModel.Details.Add(detailResultModel);
            }

            return resultModel;
        }

        public async Task<UserDepartByUserIdResultModel> GetUserDepartByUserIdAsync(UserDepartByUserIdParamModel model)
        {
            UserDepartByUserIdResultModel resultModel = new UserDepartByUserIdResultModel();
            if (model.UserIds == null || !model.UserIds.Any())
            {
                return resultModel;
            }

            model.UserIds = model.UserIds.Distinct().ToList();
            var tempusers = await this.baseRepository.CommonRepository.GetEntitiesAsync<t_user>(model.UserIds);
            var departments = await this.baseRepository.CommonRepository.GetEntitiesAsync<t_department>(tempusers.Where(t => !string.IsNullOrEmpty(t.depart_id)).Select(t => t.depart_id).ToList());
            var parentIds = departments.Where(t => !string.IsNullOrEmpty(t.parent_id)).Select(t => t.parent_id).ToList();
            var parentDepartments = parentIds.Any() ? await this.baseRepository.CommonRepository.GetEntitiesAsync<t_department>(parentIds) : new List<t_department>();
            var topparentIds = parentDepartments.Where(t => !string.IsNullOrEmpty(t.parent_id)).Select(t => t.parent_id).ToList();
            var topparentDepartments = topparentIds.Any() ? await this.baseRepository.CommonRepository.GetEntitiesAsync<t_department>(topparentIds) : new List<t_department>();

            var alldeparts = new List<t_department>();
            alldeparts.AddRange(departments);
            alldeparts.AddRange(parentDepartments);
            alldeparts.AddRange(topparentDepartments);

            var userIds = alldeparts.Where(t => !string.IsNullOrEmpty(t.user_id)).Select(t => t.user_id).ToList();
            var aliasUserIds = alldeparts.Where(t => !string.IsNullOrEmpty(t.alias_user_id)).Select(t => t.alias_user_id).ToList();
            userIds.AddRange(aliasUserIds);
            var users = userIds.Any() ? await this.baseRepository.CommonRepository.GetEntitiesAsync<t_user>(userIds) : new List<t_user>();

            foreach (var u in tempusers)
            {
                var depart = departments.FirstOrDefault(t => t.id == u.depart_id);
                var user = users.FirstOrDefault(t => t.id == depart?.user_id);
                var aliasuser = users.FirstOrDefault(t => t.id == depart?.alias_user_id);
                var shopDepart = alldeparts.FirstOrDefault(t => t.id == depart?.parent_id);
                var sectionDepart = shopDepart != null ? alldeparts.FirstOrDefault(t => t.id == shopDepart?.parent_id) : null;

                var shopuser = users.FirstOrDefault(t => t.id == shopDepart?.user_id);
                var sectionuser = users.FirstOrDefault(t => t.id == sectionDepart?.user_id);

                UserDepartByUserIdDetailResultModel detailResultModel = new UserDepartByUserIdDetailResultModel()
                {
                    UserCode = u.code,
                    UserId = u.id,
                    UserName = u.name,
                    DepartId = depart?.id,
                    DepartCode = depart?.code,
                    DepartName = depart?.name,
                    DepartUserCode = user?.code,
                    DepartUserName = user?.name,
                    DepartUserId = user?.id,
                    DepartAliasUserCode = aliasuser?.code,
                    DepartAliasUserId = aliasuser?.id,
                    DepartAliasUserName = aliasuser?.name,
                    SectionDepartCode = sectionDepart?.code,
                    SectionDepartId = sectionDepart?.id,
                    SectionDepartName = sectionDepart?.name,
                    SectionUserCode = sectionuser?.code,
                    SectionUserId = sectionuser?.id,
                    SectionUserName = sectionuser?.name,
                    ShopDepartId = shopDepart?.id,
                    ShopDepartCode = shopDepart?.code,
                    ShopDepartName = shopDepart?.name,
                    ShopUserCode = shopuser?.code,
                    ShopUserId = shopuser?.id,
                    ShopUserName = shopuser?.name,
                };

                resultModel.Details.Add(detailResultModel);
            }

            return resultModel;
        }

        public async Task<DepartLineByUserResultModel> GetDepartLineByUserByUserIdAsync(DepartLineByUserParamModel model)
        {
            DepartLineByUserResultModel resultModel = new DepartLineByUserResultModel();
            if (model.UserIds == null || !model.UserIds.Any())
            {
                return resultModel;
            }

            var users = await this.baseRepository.CommonRepository.GetEntitiesAsync<t_user>(model.UserIds);
            var departIds = users.Where(t => !string.IsNullOrEmpty(t.depart_id)).Select(t => t.depart_id).ToList();
            var departments = departIds.Any() ? await this.baseRepository.CommonRepository.GetEntitiesAsync<t_department>(departIds) : new List<t_department>();

            DepartLineParamModel departLineParam = new DepartLineParamModel();
            departLineParam.DepartCodes = departments.Select(t => t.code).ToList();
            var departLine = await GetDepartLineByDepartCodeAsync(departLineParam);

            foreach (var user in users)
            {
                var detail = new DepartLineByUserDetailResultModel() { SrcUserCode = user.code, SrcUserId = user.id, SrcUserName = user.name };
                var depart = departments.FirstOrDefault(t => t.id == user.depart_id);
                var departLineByDepart = departLine.Details.FirstOrDefault(t => t.DepartCode == depart?.code);
                if (departLineByDepart != null)
                {
                    LibSysUtils.CopyObject(detail, departLineByDepart);
                }

                resultModel.Details.Add(detail);
            }

            return resultModel;
        }

        public async Task<UserLeaderResultModel> GetUserLeaderByUserIdAsync(UserLeaderParamModel model)
        {
            UserLeaderResultModel resultModel = new UserLeaderResultModel();
            if (model.UserIds == null || !model.UserIds.Any())
            {
                return resultModel;
            }

            var users = await this.baseRepository.CommonRepository.GetEntitiesAsync<t_user>(model.UserIds);
            var departIds = users.Where(t => !string.IsNullOrEmpty(t.depart_id)).Select(t => t.depart_id).ToList();
            var departmentusers = model.UserIds.Any() ? await this.baseRepository.CommonRepository.GetEntitiesAsync<t_department>(null, t => (model.UserIds.Contains(t.user_id) || model.UserIds.Contains(t.alias_user_id)) && t.level != 2) : new List<t_department>();
            var departments = departIds.Any() ? await this.baseRepository.CommonRepository.GetEntitiesAsync<t_department>(departIds) : new List<t_department>();
            var userIds = departments.Where(t => !string.IsNullOrEmpty(t.user_id)).Select(t => t.user_id).ToList();
            var departusers = userIds.Any() ? await this.baseRepository.CommonRepository.GetEntitiesAsync<t_user>(userIds) : new List<t_user>();

            var userPostIds = users.Where(t => !string.IsNullOrEmpty(t.user_post_id)).Select(t => t.user_post_id).Distinct().ToList();

            var userPosts = await this.baseRepository.CommonRepository.GetEntitiesAsync<t_user_post>(userPostIds);
            var operatePostName = this.GetMessage("00100004");

            foreach (var user in users)
            {
                //// 部门
                var depart = departments.FirstOrDefault(t => t.id == user.depart_id);
                //// 部门负责人
                var departUser = departusers.FirstOrDefault(t => t.id == depart.user_id);
                var leadDept = departmentusers.FirstOrDefault(t => t.user_id == user.id);

                if (leadDept == null)
                {
                    leadDept = depart;
                }
                else
                {
                    departUser = users.FirstOrDefault(t => t.id == user.id);
                    depart = departmentusers.FirstOrDefault(t => t.id == leadDept.id);
                }

                var userpostname = userPosts.FirstOrDefault(t => t.id == user.user_post_id)?.name;

                UserLeaderDetailResultModel detailResultModel = new UserLeaderDetailResultModel()
                {
                    DepartCode = depart?.code,
                    DepartName = depart?.name,
                    UserCode = user?.code,
                    UserName = user?.name,
                    UserId = user?.id,
                    LeaderDepartCode = departUser != null ? leadDept?.code : null,
                    LeaderDepartName = departUser != null ? leadDept?.name : null,
                    LeaderDepartId = departUser != null ? leadDept?.id : null,
                    LeaderUserCode = departUser?.code,
                    LeaderUserId = departUser?.id,
                    LeaderUserName = departUser?.name,
                    IsOperateUser = string.Compare(operatePostName, userpostname, true) == 0 || (!departmentusers.Any(t => t.user_id == user.id || t.alias_user_id == user.id) && depart != null && !string.IsNullOrEmpty(depart.user_id) && depart.user_id != user.id),
                };

                resultModel.Details.Add(detailResultModel);
            }

            return resultModel;
        }

        public async Task<bool> UpdateDepartLeaderUserAsync(UpdateDepartLeaderUserParamModel model)
        {
            if (!model.Details.Any())
            {
                return true;
            }

            var codes = model.Details.Select(t => t.DepartCode).ToList();
            var departs = await this.baseRepository.CommonRepository.GetEntitiesAsync<t_department>(null, t => codes.Contains(t.code));

            List<t_department> updateDeparts = new List<t_department>();

            departs.ForEach(t =>
            {
                var detail = model.Details.FirstOrDefault(t1 => t1.DepartCode == t.code);

                if (detail != null)
                {
                    t.user_id = detail.UserId;
                    if (!string.IsNullOrEmpty(detail.AliasUserId))
                    {
                        t.alias_user_id = detail.AliasUserId;
                    }

                    updateDeparts.Add(t);
                }
            });

            await this.baseRepository.CommitChangesByCommonAsync(() =>
            {
                this.baseRepository.CommonRepository.UpdateEntities(updateDeparts);
            });

            return true;
        }

        public async Task<List<AllDepartModel>> GetAllDepartByOrgIdAsync(ApiParam apiParam)
        {
            if (string.IsNullOrEmpty(apiParam.OrgId))
            {
                throw new CommonException("OrgId is request");
            }

            var m = await this.baseRepository.CommonRepository.GetEntitiesAsync<t_department>(new ApiParam(apiParam.OrgId) { OrgType = FilterOrgTypeEnum.OnlyOrg }, t => t.enable_status == 0);
            if (m.Any())
            {
                List<AllDepartModel> allDeparts = new List<AllDepartModel>();
                allDeparts = GetChildList(m, allDeparts, null);
                return allDeparts;
            }

            return new List<AllDepartModel>();
        }

        /// <summary>
        /// 获取公告
        /// </summary>
        /// <param name="apiParam"></param>
        /// <returns></returns>
        public async Task<List<t_notice>> GetNoticesAsync(ApiParam apiParam)
        {
            if (string.IsNullOrEmpty(apiParam.OrgId))
            {
                throw new CommonException("OrgId is request");
            }

            Dictionary<string, int> orders = new Dictionary<string, int>();
            orders.Add("modify_time", 1);
            var notices = await this.baseRepository.CommonRepository.GetOrderPageEntitiesAsync<t_notice>(t => t.org_ids.Contains(apiParam.OrgId) && t.platform.Contains(apiParam.Keyword), orders, 0, 5);
            return notices.Data;
        }

        /// <summary>
        /// 分页获取公告
        /// </summary>
        /// <param name="modelRequest"></param>
        /// <returns></returns>
        public async Task<ApiPagedResult<NoticeModel>> GetNoticesAsync(ModelOrderPageRequest modelRequest)
        {
            var notices = this.baseRepository.CommonRepository.GetOrderPageEntities<t_notice>(modelRequest.OrderPageParam);
            ApiPagedResult<NoticeModel> noticeModelResult = new ApiPagedResult<NoticeModel>();
            List<NoticeModel> noticeModelList = new List<NoticeModel>();
            var orgs = await this.baseRepository.CommonRepository.GetEntitiesAsync<t_organization>(t => t.enable_status == 0);

            if (notices.Data != null)
            {
                foreach (var notice in notices.Data)
                {
                    NoticeModel noticeModel = new NoticeModel();
                    noticeModel.Id = notice.id;
                    noticeModel.OrgId = notice.org_id;
                    noticeModel.Title = notice.title;
                    noticeModel.Content = notice.content;
                    noticeModel.ModifyTime = notice.modify_time;
                    noticeModel.OrgName = string.Empty;
                    noticeModel.Platform = string.Empty;
                    var orgIds = notice.org_ids.Split(",");

                    foreach (var orgId in orgIds)
                    {
                        var org = orgs.Where(t => t.id == orgId).FirstOrDefault();
                        if (noticeModel.OrgName == string.Empty)
                        {
                            noticeModel.OrgName += org.name;
                        }
                        else
                        {
                            noticeModel.OrgName += "," + org.name;
                        }
                    }

                    var platForms = notice.platform.Split(",");

                    foreach (var plat in platForms)
                    {
                        var platName = string.Empty;
                        switch (plat)
                        {
                            case "0":
                                platName = Enum.GetName(typeof(PlatformTypeEnum), PlatformTypeEnum.管理端);
                                break;
                            case "1":
                                platName = Enum.GetName(typeof(PlatformTypeEnum), PlatformTypeEnum.操作端);
                                break;
                            case "2":
                                platName = Enum.GetName(typeof(PlatformTypeEnum), PlatformTypeEnum.手持端);
                                break;
                        }

                        if (noticeModel.Platform == string.Empty)
                        {
                            noticeModel.Platform += platName;
                        }
                        else
                        {
                            noticeModel.Platform += "," + platName;
                        }
                    }

                    noticeModelList.Add(noticeModel);
                }
            }

            noticeModelResult.Data = noticeModelList;
            noticeModelResult.TotalCount = notices.TotalCount;

            return noticeModelResult;
        }

        /// <summary>
        /// 保存公告
        /// </summary>
        /// <param name="modelRequest"></param>
        /// <returns></returns>
        public async Task<bool> SaveNotice(ModelSaveRequest modelRequest)
        {
            await this.baseRepository.CommonModelRepository.SaveModelsAsync(modelRequest);
            var notices = modelRequest.Details[0].ModelData.ToObjectFromJson<List<t_notice>>();
            var notice = notices.FirstOrDefault();
            NoticeModel noticeModel = new NoticeModel();
            noticeModel.Title = notice.title;
            noticeModel.Content = notice.content;
            noticeModel.OrgId = notice.org_id;
            noticeModel.IsSendLCP = notice.is_lcp;
            noticeModel.OrgIds = notice.org_ids;

            // 发送lcp消息
            if (noticeModel.IsSendLCP)
            {
                string miniUrl = this.configuration["MiniUrl"];
                noticeModel.Content = LibSysUtils.Html2Text(noticeModel.Content);
                var r = await WebApiUtils.PostAsync<ApiActionResult<bool>>($"{miniUrl}/api/UpExt/ManageData/SendNotice", noticeModel);
            }

            return true;
        }

        public async Task<DepartTreeResultModel> GetDepartTreeAsync(DepartTreeParamModel model)
        {
            DepartTreeResultModel ret = new DepartTreeResultModel();
            List<t_department> departs = null;
            if (!model.DepartIds.Any() && model.DepartCodes.Any())
            {
                departs = await this.baseRepository.CommonRepository.GetEntitiesAsync<t_department>(null, t => model.DepartCodes.Contains(t.code));
                model.DepartIds = departs.Select(t => t.id).ToList();
            }
            else
            {
                departs = await this.baseRepository.CommonRepository.GetEntitiesAsync<t_department>(model.DepartIds);
            }

            if (!model.DepartIds.Any())
            {
                return ret;
            }

            departs.ForEach(t =>
            {
                ret.Details.Add(new DepartTreeDetailResultModel() { DepartId = t.id, DepartCode = t.code, DepartName = t.name });
            });

            await GetDepartTreeByParentAsync(departs, ret);
            foreach (var detail in ret.Details)
            {
                await GetDepartTreeByChildrenAsync(detail.DepartId, detail, null);
            }

            return ret;
        }

        public async Task<IQCAreaModel> GetIQCAreaModelAsync(ApiParam apiParam)
        {
            if (string.IsNullOrEmpty(apiParam.Keyword))
            {
                throw new CommonException("keyword is request");
            }

            var m = await this.baseRepository.CommonRepository.GetEntityAsync<t_iqc_area>(apiParam.Keyword);
            return GetIQCAreaModel(m);
        }

        public async Task<IQCAreaModel> GetIQCAreaModelByCodeAsync(ApiParam apiParam)
        {
            if (string.IsNullOrEmpty(apiParam.Keyword))
            {
                throw new CommonException("keyword is request");
            }

            var m = await this.baseRepository.CommonRepository.GetEntitiesAsync<t_iqc_area>(p => p.code == apiParam.Keyword);
            return GetIQCAreaModel(m.FirstOrDefault());
        }

        public async Task<List<UserCertificateModel>> GetCertificatesAsync(ApiParam apiParam)
        {
            if (string.IsNullOrEmpty(apiParam.Keyword))
            {
                throw new CommonException("keyword is request");
            }

            var userCertificates = await this.baseRepository.CommonRepository.GetEntitiesAsync<t_user_certificate>(apiParam, t => t.user_id == apiParam.Keyword);
            List<UserCertificateModel> userCertificateModel = new List<UserCertificateModel>();

            foreach (var certificate in userCertificates)
            {
                userCertificateModel.Add(GetUserCertificateModel(apiParam.Keyword, certificate));
            }

            return userCertificateModel;
        }

        /// <summary>
        /// 获取部门信息集合
        /// </summary>
        /// <returns></returns>
        public async Task<List<DepartModel>> GetDepartsAsync(DepartsModel model)
        {
            var departs = await baseRepository.CommonRepository.GetEntitiesAsync<t_department>(c => true);
            if (!model.DepartId.IsNullOrEmpty())
            {
                departs = departs.Where(c => c.id != model.DepartId).ToList();
            }

            if (model.Levels.Any())
            {
                departs = departs.Where(c => model.Levels.Contains(c.level)).ToList();
            }

            var list = new List<DepartModel>();
            foreach (var depart in departs)
            {
                var info = new DepartModel();
                info.DepartCode = depart.code;
                info.DepartName = depart.name;
                info.ParentId = depart.parent_id;
                info.DepartId = depart.id;
                info.UserId = depart.user_id;
                info.Level = depart.level;
                info.OrgId = depart.org_id;
                list.Add(info);
            }

            if (model.IsGetParentsModel)
            {
                var parentIds = departs.Where(c => !c.parent_id.IsNullOrEmpty()).Select(c => c.parent_id).Distinct().ToList(); ////获取父级部门ID集合
                if (model.IsGetAllParentsModel)
                {
                    GetParentIds(parentIds, parentIds); ////获取所有父级部门ID集合
                }

                var parents = await baseRepository.CommonRepository.GetEntitiesAsync<t_department>(parentIds);
                foreach (var depart in parents)
                {
                    var info = new DepartModel();
                    info.DepartCode = depart.code;
                    info.DepartName = depart.name;
                    info.ParentId = depart.parent_id;
                    info.DepartId = depart.id;
                    info.UserId = depart.user_id;
                    info.Level = depart.level;
                    list.Add(info);
                }
            }

            return list.GroupBy(c => c.DepartId).Select(c => c.First()).ToList(); ////对象集合使用Distinct失效，故使用GroupBy去重
        }

        /// <summary>
        /// 根据用户ID获取所属部门下的用户集合
        /// </summary>
        /// <param name="departId"></param>
        /// <param name="isGetAllChildrenDepartModel"></param>
        /// <returns></returns>
        public async Task<List<DepartUserResultModel>> GetUsersByUserIdAsync(UsersByUserIdModel model)
        {
            var userId = tokenService.GetUserToken()?.UId;
            var user = await baseRepository.CommonRepository.GetEntityAsync<t_user>(userId);
            var departIds = new List<string> { await GetParentId(user?.depart_id, model.DepartLevel) };
            if (model.IsGetAllChildrenDepartModel)
            {
                GetdepIds(departIds, departIds); ////获取所有子级部门ID集合
            }

            var departs = await baseRepository.CommonRepository.GetEntitiesAsync<t_department>(departIds);
            var users = await baseRepository.CommonRepository.GetEntitiesAsync<t_user>(c => departIds.Contains(c.depart_id));
            var list = new List<DepartUserResultModel>();
            foreach (var item in users)
            {
                list.Add(new DepartUserResultModel
                {
                    UserId = item.id,
                    UserCode = item.code,
                    UserName = item.name,
                    DepartName = departs.FirstOrDefault(c => c.id == item.depart_id)?.name
                });
            }

            list = list.OrderBy(c => c.DepartName).ToList();
            return list;
        }

        /// <summary>
        /// 根据用户ID和层级向上获取部门信息
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public async Task<DepartModel> GetDepartByUserIdAndLevelAsync(DepartByUserIdAndLevelModel model)
        {
            var result = new DepartModel();
            var userId = tokenService.GetUserToken()?.UId;
            if (userId.IsNullOrEmpty())
            {
                userId = model.UserId;
            }

            var user = await baseRepository.CommonRepository.GetEntityAsync<t_user>(userId);
            var departId = await GetParentId(user?.depart_id, model.Level);
            if (departId.IsNullOrEmpty())
            {
                return result;
            }

            var depart = await baseRepository.CommonRepository.GetEntityAsync<t_department>(departId);
            if (depart == null)
            {
                return result;
            }
            else
            {
                result.DepartId = departId;
                result.DepartCode = depart.code;
                result.DepartName = depart.name;
                result.Level = depart.level;
                result.IsLine = depart.is_line;
                result.IsStatis = depart.is_statis;
                return result;
            }
        }

        public async Task<int> GetNewUserCountAsync(List<string> userIds)
        {
            var users = await this.baseRepository.CommonRepository.GetEntitiesAsync<t_user>(userIds);
            if (users == null || !users.Any())
            {
                return 0;
            }

            return users.Count(p => p.entry_date > DateTime.Now.Date.AddDays(-7));
        }

        private async Task GetDepartTreeByParentAsync(List<t_department> departs, DepartTreeResultModel ret)
        {
            var parentIds = departs.Where(t => !string.IsNullOrEmpty(t.parent_id)).Select(t => t.parent_id).ToList();
            if (!parentIds.Any())
            {
                return;
            }

            var temps = await this.baseRepository.CommonRepository.GetEntitiesAsync<t_department>(parentIds);

            departs.Where(t => !string.IsNullOrEmpty(t.parent_id)).ForEach(t =>
             {
                 var d = temps.FirstOrDefault(t1 => t1.id == t.parent_id);
                 if (d == null)
                 {
                     return;
                 }

                 var depart = ret.Details.FirstOrDefault(t1 => t1.DepartId == t.id || t1.ParentIds.Contains(t.id));

                 if (depart == null)
                 {
                     return;
                 }

                 depart.ParentIds.Add(d.id);
                 depart.ParentCodes.Add(d.code);

                 depart.Parents.Add(new DepartTreeDetailParentResultModel() { DepartCode = d.code, DepartId = d.id, DepartName = d.name });
             });

            if (temps.Any(t => !string.IsNullOrEmpty(t.parent_id)))
            {
                await GetDepartTreeByParentAsync(temps, ret);
            }
        }

        private async Task GetDepartTreeByChildrenAsync(string parentId, DepartTreeDetailResultModel detail, DepartTreeDetailChildrenResultModel resultModel)
        {
            var temps = await this.baseRepository.CommonRepository.GetEntitiesAsync<t_department>(null, t => t.parent_id == parentId);

            foreach (var s in temps)
            {
                detail.ChildrenIds.Add(s.id);
                detail.ChildrenCodes.Add(s.code);
                var est = new DepartTreeDetailChildrenResultModel() { DepartCode = s.code, DepartId = s.id, DepartName = s.name };

                if (resultModel != null)
                {
                    resultModel.Childrens.Add(est);
                }
                else
                {
                    detail.Childrens.Add(est);
                }

                await GetDepartTreeByChildrenAsync(s.id, detail, est);
            }
        }

        private async Task<List<DepartmentUserModel>> GetDepartmentUserModels(List<string> userIds)
        {
            if (!userIds.Any())
            {
                throw new CommonException("Keyword is request");
            }

            ApiParam apiParam = new ApiParam();
            ////var member = await this.baseRepository.CommonRepository.GetEntitiesAsync<t_member>(p => depIds.Contains(p.depart_id));
            ////var userIds = member.Select(p => p.user_id).ToList();
            var users = await this.baseRepository.CommonRepository.GetEntitiesAsync<t_user>(userIds);
            var result = new List<DepartmentUserModel>();
            ////if (member == null || !member.Any())
            ////{
            ////    return null;
            ////}

            users.ForEach((o) =>
            {
                ///var user = users.Where(p => p.id == o.id).FirstOrDefault();
                var item = new DepartmentUserModel();
                item.UserCode = o?.code;
                item.UserName = o?.name;
                item.UserId = o?.id;
                item.DepId = o.depart_id;
                item.Id = o.id;
                item.PositionCode = o?.position_code;
                result.Add(item);
            });

            return result;
        }

        private void GetdepIds(List<string> ids, List<string> result)
        {
            var deps = this.baseRepository.CommonRepository.GetEntities<t_department>(p => ids.Contains(p.parent_id));
            if (!deps.Any())
            {
                return;
            }

            var childIds = deps.Select(p => p.id).ToList();
            result.AddRange(childIds);
            GetdepIds(childIds, result);
        }

        private void GetParentIds(List<string> ids, List<string> result)
        {
            var deps = this.baseRepository.CommonRepository.GetEntities<t_department>(p => ids.Contains(p.id));
            if (!deps.Any())
            {
                return;
            }

            var parentDept = deps.Where(p => p.parent_id != null).ToList();
            if (parentDept.Count > 0)
            {
                var childIds = parentDept.Select(p => p.parent_id).ToList();
                result.AddRange(childIds);
                GetParentIds(childIds, result);
            }
            else
            {
                var childIds = parentDept.Select(p => p.id).ToList();
                result.AddRange(childIds);
                GetParentIds(childIds, result);
            }
        }

        private UserModel GetUserModel(t_user m)
        {
            if (m == null)
            {
                return null;
            }

            var u = new UserModel()
            {
                Code = m.code,
                Id = m.id,
                Name = m.name,
                DepartId = m.depart_id,
                OrgId = m.org_id,
                ApiKey = m.api_key,
                ChapterCode = m.chapter_code,
                LcpCode = m.user_lcp_code,
                IqcAreaId = m.area_id,
                IqcPowerLevel = m.iqc_power_level,
                SuperiorLcpCode = m.superior_lcp_code,
                ResponsibleId = m.responsible_id,
            };
            return u;
        }

        private UserFullModel GetUserFullModel(t_user m, t_user_post post)
        {
            if (m == null)
            {
                return null;
            }

            var u = new UserFullModel()
            {
                Code = m.code,
                Id = m.id,
                OrgId = m.org_id,
                Name = m.name,
                DepartId = m.depart_id,
                PostCode = post?.code,
                PostName = post?.name,
                Phone = m.phone,
                UserLCPCode = m.user_lcp_code,
                AttFiles = m.att_files,
                ApiKey = m.api_key,
                DirIndirClass = m.dir_indir_class
            };
            return u;
        }

        private MemberModel GetMemberModel(t_member m)
        {
            if (m == null)
            {
                return null;
            }

            var u = new MemberModel()
            {
                OrgId = m.org_id,
                MemberCode = m.code,
                MemberId = m.id,
                MemberName = m.name,
                Password = m.password,
                UserId = m.user_id,
                IqcAreaId = m.area_id,
                IqcPowerLevel = m.iqc_power_level,
                ResponsibleId = m.responsible_id,
                SuperiorLcpCode = m.superior_lcp_code,
            };
            return u;
        }

        private DepartModel GetDepartModel(t_department m)
        {
            if (m == null)
            {
                return null;
            }

            var u = new DepartModel()
            {
                OrgId = m.org_id,
                DepartCode = m.code,
                DepartId = m.id,
                DepartName = m.name,
                ParentId = m.parent_id,
                ApiKey = m.api_key,
                UserId = m.user_id
            };
            return u;
        }

        private List<AllDepartModel> GetChildList(List<t_department> list, List<AllDepartModel> models, string parentId)
        {
            models = new List<AllDepartModel>();
            List<t_department> tempList = list.Where(c => c.parent_id == parentId).ToList();
            if (tempList.Count == 0)
            {
                return null;
            }

            foreach (var temp in tempList)
            {
                AllDepartModel node = new AllDepartModel();
                node.label = temp.name;
                node.value = temp.id;
                node.children = GetChildList(list, models, temp.id);

                models.Add(node);
            }

            return models;
        }

        private IQCAreaModel GetIQCAreaModel(t_iqc_area m)
        {
            if (m == null)
            {
                return null;
            }

            var u = new IQCAreaModel()
            {
                Code = m.code,
                Id = m.id,
                Name = m.name,
                EnableStatus = m.enable_status,
                Remark = m.remark,
                ResponsibleUserId = m.responsible_user_id,
                OrgId = m.org_id,
                Shelf_life = m.shelf_life,
                Table_code = m.table_code
            };
            return u;
        }

        private UserCertificateModel GetUserCertificateModel(string userId, t_user_certificate m)
        {
            if (m == null)
            {
                return null;
            }

            var u = new UserCertificateModel()
            {
                UserId = userId,
                Code = m.code,
                Name = m.name,
                CertificateId = m.certificate_id
            };
            return u;
        }

        /// <summary>
        /// 获取父级部门ID
        /// </summary>
        /// <param name="departId">部门ID</param>
        /// <param name="departLevel">部门层级：3=生产课，4=生产部</param>
        /// <returns></returns>
        private async Task<string> GetParentId(string departId, int departLevel)
        {
            var parentDepartId = string.Empty;
            var depart = await baseRepository.CommonRepository.GetEntityAsync<t_department>(departId);
            if (depart == null)
            {
                return parentDepartId;
            }

            ////当前生产部符合条件，直接返回
            if (depart.level == departLevel)
            {
                return depart.id;
            }

            var parentDepart = (await baseRepository.CommonRepository.GetEntitiesAsync<t_department>(c => c.id == depart.parent_id)).FirstOrDefault();
            if (parentDepart == null)
            {
                return parentDepartId;
            }

            if (parentDepart.level == departLevel)
            {
                return parentDepartId = parentDepart.id;
            }
            else
            {
                return await GetParentId(parentDepart.id, departLevel);
            }
        }
    }
}
